package org.qframe.quickc;

import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.apt.AnnotationProcessorFactory;
import com.sun.mirror.declaration.AnnotationTypeDeclaration;
import com.sun.mirror.declaration.ClassDeclaration;
import com.sun.mirror.declaration.TypeDeclaration;
import com.sun.mirror.util.DeclarationVisitors;
import com.sun.mirror.util.SimpleDeclarationVisitor;
import java.util.Collection;
import java.util.Set;
import java.util.Arrays;
import java.util.Collections;

/*
 * This class is used to run an annotation processor that lists class
 * names.  The functionality of the processor is analogous to the
 * ListClass doclet in the Doclet Overview.
 */
public class Sample implements AnnotationProcessorFactory {
    // Process any set of annotations

    static {
        System.out.println("SAMPLE LOADED");
    }
    private static final Collection<String> supportedAnnotations = Collections.unmodifiableCollection(Arrays.asList("*"));
    // No supported options
    private static final Collection<String> supportedOptions = Collections.emptySet();

    public Collection<String> supportedAnnotationTypes() {
        return supportedAnnotations;
    }

    public Collection<String> supportedOptions() {
        return supportedOptions;
    }

    public AnnotationProcessor getProcessorFor(
            Set<AnnotationTypeDeclaration> atds,
            AnnotationProcessorEnvironment env) {
        return new ListClassAp(env);
    }

    private static class ListClassAp implements AnnotationProcessor {

        private final AnnotationProcessorEnvironment env;

        static {
            System.out.println("ListClassAp LOADED");
        }

        ListClassAp(AnnotationProcessorEnvironment env) {
            System.out.println("ListClassAp  instance LOADED");
            this.env = env;
        }

        public void process() {
            for (TypeDeclaration typeDecl : env.getSpecifiedTypeDeclarations()) {
                typeDecl.accept(DeclarationVisitors.getDeclarationScanner(new ListClassVisitor(),
                        DeclarationVisitors.NO_OP));
            }
        }

        private static class ListClassVisitor extends SimpleDeclarationVisitor {

            public void visitClassDeclaration(ClassDeclaration d) {
                System.out.println(d.getQualifiedName());
            }
        }
    }
}
